package org.amuthu.expression.binary;

import org.amuthu.expression.Expression;
import org.amuthu.expression.exception.TypeMismatchException;
import org.amuthu.parser.ExpressionVisitor;

/**
 * Abstract base class for the comparison expressions:
 * <code>>, <, ==, !=, <=, >=</code>
 */
public class ComparisionExpression extends BinaryExpression
{

   private ComparisionExprType exprType;

   public ComparisionExprType getExprType()
   {
      return exprType;
   }

   /**
    * Create a new comparison expression with the given left and
    * right arguments.
    */
   public ComparisionExpression(ComparisionExprType exprType, Expression left, Expression right)
   {
      super(left, right);
      this.exprType = exprType;
   }

   /**
    * Check the input arguments to the expression. They can only be
    * {@link #INTEGER_TYPE} or {@link #FLOAT_TYPE}. Both must be the same!
    *
    * @return	the type of the expression
    */
   @Override
   public int checkType() throws TypeMismatchException
   {
      // left & right types must be the same and not boolean or quote
      int leftType = getChild(0).checkType();
      int rightType = getChild(1).checkType();

      if (leftType == rightType && (leftType == FLOAT_TYPE || leftType == INTEGER_TYPE))
      {
         return getType();
      }

      if ((leftType == FLOAT_TYPE || leftType == INTEGER_TYPE) && (rightType == FLOAT_TYPE || rightType == INTEGER_TYPE))
      {
         return getType();
      }
      else
      {
         String types = getChild(0).getType() + " , " + getChild(1).getType();
         String expectedTypes = FLOAT_TYPE + "," + FLOAT_TYPE;

         throw new TypeMismatchException(this, types, expectedTypes);
      }
   }

   /**
    * Get the type of the expression.
    *
    * @return {@link #BOOLEAN_TYPE}.
    */
   @Override
   public int getType()
   {
      return BOOLEAN_TYPE;
   }

   
   @Override
   public String toString()
   {
      switch (exprType)
      {
         case NOT_EQUALTO:
            return super.toString(" != ");

         case EQUALTO:
            return super.toString(" == ");

         case LESS_THAN:
            return super.toString(" < ");

         case LESS_THAN_EQUAL:
            return super.toString(" <= ");

         case GREATER_THAN:
            return super.toString(" > ");

         case GREATER_THAN_EQUAL:
            return super.toString(" >= ");

         default:
            throw new AssertionError();
      }

   }

   @Override
   public void accept(ExpressionVisitor visitor)
   {
      visitor.visit(this);
   }
}
